/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_tick.c
 * @brief    滴答服务（仅在滴答钩子、定时中断钩子、定时查询钩子中调用）
 * @author   迟凯峰
 * @version  V1.0.0
 * @date     2023.10.20
 ******************************************************************************/

#include "os_var.h"
#include "os_api.h"



/*
 * 任务
 */

/* 挂起任务 */
s_ecode_t st_suspend_task(s_tasknode_tsp node) MCUCFG_C51USING
{
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	#endif
	if(node->status < OS_STATUS_SUSPENDED){
		node->status |= OS_STATUS_SUSPENDED;
		return OS_ECODE_NOERROR;
	}
	if(node->status & OS_STATUS_SUSPENDED){
		return OS_ECODE_TASKSUSPENDED;
	}
	if(node->status & OS_STATUS_STOPPED){
		return OS_ECODE_TASKSTOPPED;
	}
	if(node->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/* 恢复任务 */
s_ecode_t st_resume_task(s_tasknode_tsp node) MCUCFG_C51USING
{
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	#endif
	if(node->status & OS_STATUS_SUSPENDED){
		node->status &= (~OS_STATUS_SUSPENDED & 0xFF);
		return OS_ECODE_NOERROR;
	}
	if(node->status < OS_STATUS_STOPPED){
		return OS_ECODE_TASKUNSUSPENDED;
	}
	if(node->status & OS_STATUS_STOPPED){
		return OS_ECODE_TASKSTOPPED;
	}
	if(node->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/* 删除任务 */
s_ecode_t st_delete_task(s_tasknode_tsp node) MCUCFG_C51USING
{
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	#endif
	if(node->status < OS_STATUS_DELETED){
		node->status = OS_STATUS_DELETED;
		return OS_ECODE_NOERROR;
	}
	if(node->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/* 设置任务优先级 */
s_ecode_t st_set_taskpri(s_tasknode_tsp node, s_u8_t pri) MCUCFG_C51USING
{
	#if SYSCFG_TASKCREATEMODE == __DYNAMIC__
	if(node == NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	#endif
	if(node->status < OS_STATUS_STOPPED){
		if(node->pri != pri){
			node->pri = pri;
			sSetTaskPri(node);
			return OS_ECODE_NOERROR;
		}
		else{
			return OS_ECODE_TASKPRIUNCHANGED;
		}
	}
	if(node->status & OS_STATUS_STOPPED){
		return OS_ECODE_TASKSTOPPED;
	}
	if(node->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/* 设置阻塞（时间）*/
s_bool_t st_set_block(s_tasknode_tsp node, s_delay_t tick) MCUCFG_C51USING
{
	if(node->status == OS_STATUS_BLOCKED || node->status == OS_STATUS_FLOATING){
		s_delay_loader[node->tid] = tick;
		if(!tick){
			node->status = OS_STATUS_READY;
		}
		return true;
	}
	return false;
}

/* 清除阻塞（状态）*/
s_bool_t st_clear_block(s_tasknode_tsp node) MCUCFG_C51USING
{
	if(node->status == OS_STATUS_BLOCKED || node->status == OS_STATUS_FLOATING){
		s_delay_loader[node->tid] = 0;
		node->status = OS_STATUS_READY;
		return true;
	}
	return false;
}



/*
 * 计数信号量
 */
#if SYSCFG_SEMAPHORE == __ENABLED__
/* 获取 */
s_bool_t st_take_semaphore(s_sem_tsp sem) MCUCFG_C51USING
{
	if(sem->counter){
		(sem->counter)--;
		return true;
	}
	return false;
}

/* 释放 */
void st_give_semaphore(s_sem_tsp sem) MCUCFG_C51USING
{
	if(sem->counter < sem->maximum){
		sem->counter++;
	}
}

#endif



/*
 * 飞信
 */
#if SYSCFG_FETION == __ENABLED__
/* 接收飞信 */
m_fetion_t st_recv_fetion(m_fetion_t _OBJ_MEM_ *ft) MCUCFG_C51USING
{
	m_fetion_t fetion = *ft;
	*ft = false;
	return fetion;
}

#endif



/*
 * 消息邮箱
 */
#if SYSCFG_MAILBOX == __ENABLED__
/* 发送邮件 */
void st_send_mail(void _OBJ_MEM_ *gm, void *lm, size_t size, s_bool_t _OBJ_MEM_ *gf) MCUCFG_C51USING
{
	static s_mbox_ts accessor;
	accessor.gm = gm;
	#if SYSCFG_MAILBOX_ACCESSMECHANISM == 1
	accessor.lm = lm;
	accessor.lf = true;
	#endif
	sWrite_MBoxAccessor(&accessor);
	s_memcpy(gm, lm, size);
	sWrite_MBoxAccessor(NULL);
	#if SYSCFG_MAILBOX_ACCESSMECHANISM == 0
	*gf = true;
	#elif SYSCFG_MAILBOX_ACCESSMECHANISM == 1
	*gf = accessor.lf;
	#endif
}

#endif



/*
 * 消息队列
 */
#if SYSCFG_MSGQUEUE == __ENABLED__
/* 接收消息 */
void *st_recv_msg(s_msgqueue_tsp queue) MCUCFG_C51USING
{
	void *msg = NULL;
	s_msgnode_tsp node;
	queue->mutex = false;
	if(!queue->counter);
	else if(queue->type == __DYNAMIC__){
		sRecvMsg_Dynamic(msg);
	}
	else{
		sRecvMsg_Static(msg);
	}
	queue->mutex = true;
	return msg;
}

/* 发送消息 */
s_ecode_t st_send_msg(s_msgqueue_tsp queue, void *msg) MCUCFG_C51USING
{
	queue->mutex = false;
	if(queue->counter == queue->len){
		queue->mutex = true;
		#if SYSCFG_DEBUGGING == __ENABLED__
		s_alarm.overflow_msgqueue = true;
		#endif
		return OS_ECODE_OVERFLOW_MSGQUEUE;
	}
	if(queue->type == __DYNAMIC__){
		s_msgnode_tsp node = NULL;
		node = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts));
		if(node == NULL){
			queue->mutex = true;
			#if SYSCFG_DEBUGGING == __ENABLED__
			s_fault.mallocfailed_msgnode = true;
			#endif
			return OS_ECODE_MALLOCFAIL_MSGNODE;
		}
		sSendMsg_Dynamic(msg);
	}
	else{
		sSendMsg_Static(msg);
	}
	queue->mutex = true;
	return OS_ECODE_NOERROR;
}

#endif



/*
 * 全局变量
 */

/* 全局变量写访问 */
void st_gvar_write(void *gv, void *lv, size_t size) MCUCFG_C51USING
{
	static s_gvar_ts accessor;
	accessor.gv = gv;
	accessor.lv = lv;
	sWrite_GVarAccessor(&accessor);
	size ? s_memcpy(gv, lv, size) : s_strcpy((char *)gv, (char *)lv);
	sWrite_GVarAccessor(NULL);
}

/* 全局变量自运算 */
void st_gvar_selfope(void *gv, void *lv, s_voidvoid_tfp fp) MCUCFG_C51USING
{
	static s_gvar_ts accessor;
	accessor.gv = gv;
	accessor.lv = lv;
	sWrite_GVarAccessor(&accessor);
	(*fp)();
	sWrite_GVarAccessor(NULL);
}
